const logger = require('../utils/logger');
const ApiResponse = require('../utils/response');

/**
 * 自定义错误类
 */
class AppError extends Error {
  constructor(message, statusCode = 500, code = null) {
    super(message);
    this.statusCode = statusCode;
    this.code = code;
    this.isOperational = true;
    Error.captureStackTrace(this, this.constructor);
  }
}

/**
 * 异步路由处理器包装器
 * 自动捕获异步错误
 */
const asyncHandler = (fn) => {
  return (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
};

/**
 * 全局错误处理中间件
 */
const errorHandler = (err, req, res, next) => {
  let error = { ...err };
  error.message = err.message;
  error.stack = err.stack;

  // 记录错误日志
  logger.error('请求处理错误', {
    message: err.message,
    stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
    url: req.originalUrl,
    method: req.method,
    ip: req.ip,
    body: process.env.NODE_ENV === 'development' ? req.body : undefined
  });

  // MySQL 错误处理
  if (err.code === 'ER_DUP_ENTRY') {
    error.message = '数据已存在';
    error.statusCode = 409;
  }

  if (err.code === 'ER_NO_REFERENCED_ROW_2') {
    error.message = '关联数据不存在';
    error.statusCode = 400;
  }

  if (err.code === 'ER_BAD_FIELD_ERROR') {
    error.message = '字段不存在';
    error.statusCode = 400;
  }

  // JWT 错误处理
  if (err.name === 'JsonWebTokenError') {
    error.message = '无效的访问令牌';
    error.statusCode = 401;
  }

  if (err.name === 'TokenExpiredError') {
    error.message = '访问令牌已过期';
    error.statusCode = 401;
  }

  // Multer 文件上传错误
  if (err.code === 'LIMIT_FILE_SIZE') {
    error.message = '文件大小超过限制';
    error.statusCode = 413;
  }

  if (err.code === 'LIMIT_UNEXPECTED_FILE') {
    error.message = '上传的文件字段不正确';
    error.statusCode = 400;
  }

  // 验证错误
  if (err.name === 'ValidationError') {
    error.message = err.message || '数据验证失败';
    error.statusCode = 422;
  }

  // 响应错误
  const statusCode = error.statusCode || 500;
  const message = error.message || '服务器内部错误';

  res.status(statusCode).json({
    code: statusCode,
    msg: message,
    ...(process.env.NODE_ENV === 'development' && {
      error: err.message,
      stack: err.stack
    }),
    timestamp: Date.now()
  });
};

/**
 * 404 处理中间件
 */
const notFoundHandler = (req, res, next) => {
  logger.warn('访问不存在的路由', {
    url: req.originalUrl,
    method: req.method,
    ip: req.ip
  });

  ApiResponse.notFound(res, '接口不存在');
};

/**
 * 进程异常处理
 */
const handleUncaughtException = () => {
  process.on('uncaughtException', (err) => {
    logger.error('未捕获的异常', {
      message: err.message,
      stack: err.stack
    });
    
    // 优雅退出
    process.exit(1);
  });
};

const handleUnhandledRejection = () => {
  process.on('unhandledRejection', (reason, promise) => {
    logger.error('未处理的 Promise 拒绝', {
      reason: reason instanceof Error ? reason.message : reason,
      stack: reason instanceof Error ? reason.stack : undefined
    });
  });
};

module.exports = {
  AppError,
  asyncHandler,
  errorHandler,
  notFoundHandler,
  handleUncaughtException,
  handleUnhandledRejection
};

